import { ETaskState } from "GameLoop/DecisionMaking/TaskDeclare/type";
import { ATeamCombat } from "GameLoop/WorldState/EntityManager/Entitys";
 
import { PositionHelper } from "utils/position/PositionHelper";
export abstract class  IDefendStrategy
{
    abstract assignTarget(room:Room,task:ITask<ITeamTaskData<"defend">>,team:ATeamCombat[],creeps:Creep[]):ETaskState;
    
    protected correctCreep(creep:Creep,workroom:string,goal:IAttackTactic):IMoveGoal|undefined
    {
        if(creep.room.name!= workroom || PositionHelper.isInExit(creep.pos))
        {
             return {pos:PositionHelper.Create({x:25,y:25,roomName:workroom}),range:21}
        }
        return goal.goal
    }
    protected correctTeam(team:ATeamCombat,workroom:string,goal:IAttackTactic):IMoveGoal|undefined
    {
        const anchor =team.getAnchor();
        if(anchor && (anchor.roomName!= workroom || PositionHelper.isInExit(team.getAnchor())))
        {
            return {pos:PositionHelper.Create({x:25,y:25,roomName:workroom}),range:21}
        }
        return goal.goal
    }
    /**
     * 对小队周围的敌方爬单位进行分组
     * @param teams 
     * @param cachecreeps 
     */ 
    protected  updateTeamAroundHostile (teams:ATeamCombat[],HostileCreep: Creep[])
    {
        teams.forEach(e=>e.setAroundHostileCreeps([]))
        for(const e of HostileCreep)
        {
            for(const t of teams)
            {
                if(t.creeps.length==0)
                {
                    continue;
                }
                const anchor = t.getAnchor();
                if(anchor &&PositionHelper.Distance(anchor,e.pos)<6)
                {
                    t.pushAroundHostileCreep([e]);
                }
            }
        }
    }


     /**
     * 对小队周围的敌方爬单位进行分组
     * @param teams 
     * @param cachecreeps 
     */ 
    protected  updateCreepAroundHostile(creeps:Creep[],HostileCreep: Creep[])
    {
        
        for(const e of HostileCreep)
        {
            creeps.forEach(creep=>
            {
                let range = 1;
                if(creep.bodyCount(RANGED_ATTACK))
                {
                    range=3;
                }
                if(creep.pos.inRangeTo(e.pos,range))
                {
                    creep.setAroundHostileCreeps([e]);
                }
            }
            )
        }
    }

    protected getMoveGoal(workroom:string,workRoom?:Room):IMoveGoal|undefined
    {
        if(Game.flags["move"]  )
        {
            return {
                pos:Game.flags["move"].pos,
                range:0
                }
        }
        else
        {
            if(workRoom)
            {
                //有视野的情况下不需要指定移动目标。
                return undefined
            }
            else
            { 
                // 没视野
                return {
                    pos:PositionHelper.Create({x:25,y:25,roomName:workroom}),
                    range:20
                }
            }
        }
    }
    // 当没有到目标房间时，先移动到目标房间。放置目标在移动会导致多次重复寻路
    /**
     * 设置攻击的跟踪，移动goal 和攻击目标
     * @param tatic 
     */
    protected setCreepTactic(creeps:Creep[],tatic:IAttackTactic,workroom:string,correct?:(creep:Creep,workroom:string,pos:IAttackTactic)=>IMoveGoal|undefined):void
    {
    //    this.memory.tactic = tatic;
        if(correct)
        {
            creeps.forEach(e=>
                {
                    const newtarget = _.clone(tatic);
                    newtarget.goal = correct(e,workroom,newtarget);
                    e.setTactic(newtarget )
                })
        }
        else 
        {
            creeps.forEach(e=>e.setTactic(tatic ))
        }
    }

    protected setTeamTractic(teams:ATeamCombat[],tatic:IAttackTactic,workroom:string,correct?:(creep:ATeamCombat,workroom:string,pos:IAttackTactic)=>IMoveGoal|undefined):void 
    {
        if(correct)
        {
            teams.forEach(e=>
                {
                    const newtarget = _.clone(tatic);
                    newtarget.goal = correct(e,workroom,newtarget);
                    e.setTactic(newtarget )
                })
        }
        else 
        {
            teams.forEach(e=>e.setTactic(tatic ))
        }
        
    }
}
